package com.xyebank.ledger.util;


import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
*
* 本工具只适用于AES/CBC/PKCS5Padding模式
* 对加密出来密文有进行Base64编码
* 解密亦然
* @author rcl:
* @version 创建时间：2018年1月5日 下午5:01:56
* 
*/
public class AesUtil {

    public static void main(String[] args) throws Exception {
		String content = "{\"mobileNo\":\"18990238900\", \"loanNo\":\"yf2f3932222\", \"zyLoanNo\":\"BO2018010900023\", \"applyTime\":\"2018-01-05 12:00:00\", \"loanState\":\"AKELOAN_SUCCESS\"}";
        System.out.println("加密前：" + content);

        String key = "abcdefghijklmnop";
        System.out.println("加密密钥和解密密钥：" + key);

        String encrypt = encryptAES(content, key, IV_STRING);
        System.out.println("加密后：" + encrypt);

        String decrypt = decryptAES(encrypt, key, IV_STRING);
        System.out.println("解密后：" + decrypt);
        
    }
    private static final String IV_STRING = "abcdefgh90871234";

    private static final String encoding = "UTF-8";

    public static String encryptAES(String content, String key, String offset)
            throws InvalidKeyException, NoSuchAlgorithmException,
            NoSuchPaddingException, UnsupportedEncodingException,
            InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {

        byte[] byteContent = content.getBytes(encoding);

        // 注意，为了能与 iOS 统一
        // 这里的 key 不可以使用 KeyGenerator、SecureRandom、SecretKey 生成
        byte[] enCodeFormat = key.getBytes(encoding);
        SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, "AES");

        byte[] initParam = offset.getBytes(encoding);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam);

        // 指定加密的算法、工作模式和填充方式
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);

        byte[] encryptedBytes = cipher.doFinal(byteContent);

        // 同样对加密后数据进行 base64 编码
        String base64 = new BASE64Encoder().encode(encryptedBytes);
        //进行url编码 去掉= ? &
        return URLEncoder.encode(base64,encoding);
    }

    public static String decryptAES(String content, String key, String offset)
            throws InvalidKeyException, NoSuchAlgorithmException,
            NoSuchPaddingException, InvalidAlgorithmParameterException,
            IllegalBlockSizeException, BadPaddingException, IOException {

        //URL解码
        content = URLDecoder.decode(content,encoding);
        // base64 解码
        byte[] encryptedBytes = new BASE64Decoder().decodeBuffer(content);

        byte[] enCodeFormat = key.getBytes(encoding);
        SecretKeySpec secretKey = new SecretKeySpec(enCodeFormat, "AES");

        byte[] initParam = offset.getBytes(encoding);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam);

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);

        byte[] result = cipher.doFinal(encryptedBytes);

        return new String(result, encoding);
    }

}
